package lib.bone.admin.controller.nepu;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Validator;
import com.alibaba.excel.EasyExcel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lib.bone.access.module.post.NepuPostService;
import lib.bone.access.module.post.domain.NepuPost;
import lib.bone.admin.controller.system.dto.TopicDTO;
import lib.bone.admin.domain.vo.UserWorkloadExportVO;
import lib.bone.audit.workload.domain.dto.AnalysisUserWorkloadDTO;
import lib.bone.audit.workload.domain.vo.*;
import lib.bone.audit.workload.service.NepuWorkloadService;
import lib.bone.common.core.domain.ResponseDTO;
import lib.bone.flow.domain.entity.FlowWork;
import lib.bone.flow.service.FlowWorkService;
import lib.bone.oss.service.IFileService;
import lib.bone.system.domain.vo.SysDeptBasic;
import lib.bone.system.domain.vo.UserBaseVO;
import lib.bone.system.module.iojob.constant.JobStatusConst;
import lib.bone.system.module.iojob.domain.IOJob;
import lib.bone.system.module.iojob.service.IOJobService;
import lib.bone.system.service.SysDeptService;
import lib.bone.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * @author kindear
 * 分析控制器
 */
@Slf4j
@RestController
@RequestMapping("analysis")
@Api(tags = "数据分析管理")
public class AnalysisController {

    @Value("${file-upload-service.path}")
    private String fileParentPath;

    @Autowired
    SysUserService userService;

    @Autowired
    SysDeptService deptService;

    @Autowired
    NepuPostService postService;

    @Autowired
    IOJobService ioJobService;

    @Autowired
    NepuWorkloadService workloadService;

    @Autowired
    IFileService fileService;





//    @WebLog(module = "bone-system")
    @Deprecated
    @GetMapping("users/workload/export")
    @ApiOperation(value = "分析用户工作量并导出")
    public ResponseDTO<Object> exportUserWorkload(@RequestParam(value = "deptId",required = false) Long deptId) {
        IOJob ioJob = ioJobService.createExportJob("工作量导出记录");
        /*
          获取全部部门信息 并构建集合
         */
        List<SysDeptBasic> depts = deptService.getAllDeptBasic();
        Map<Long,String> deptMap = new HashMap<>();
        depts.forEach(ele->{
            deptMap.put(ele.getId(),ele.getDeptName());
        });
        /*
            获取全部岗位信息，并构建集合
         */
        List<NepuPost> posts = postService.getAll();
        Map<String,String> postTypeMap = new HashMap<>();
        Map<String,String> postGradeMap = new HashMap<>();
        Map<String,String> postLevelMap = new HashMap<>();
        posts.forEach(ele->{
            postTypeMap.put(ele.getId(),ele.getPostType());
            postGradeMap.put(ele.getId(),ele.getPostGrade());
            postLevelMap.put(ele.getId(),ele.getPostLevel());
        });

        /*
          获取用户列表
         */
        List<UserBaseVO> baseVOS = userService.getAllUserBase();
        // 过滤条件
        if (Validator.isNotEmpty(deptId)){
            baseVOS = baseVOS.stream().filter(ele -> ele.getDeptId().equals(deptId)).collect(Collectors.toList());
        }
        List<UserWorkloadExportVO> exportList = new ArrayList<>();
        baseVOS.forEach(ele->{
            UserWorkloadExportVO vo = new UserWorkloadExportVO();
            BeanUtil.copyProperties(ele,vo, CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
            vo.setDeptName(deptMap.get(ele.getDeptId()));
            // 映射岗位信息
            if (Validator.isNotEmpty(ele.getPostId())){
                vo.setPostGrade(postGradeMap.get(ele.getPostId()));
                vo.setPostLevel(postLevelMap.get(ele.getPostId()));
                vo.setPostType(postTypeMap.get(ele.getPostId()));
            }
            exportList.add(vo);
        });
        // 存放 Future 结果的数组
        List<Future<AnalysisUserWorkloadDTO>> list = new ArrayList<>();
        for (UserBaseVO vo:baseVOS){
            list.add(workloadService.AnalysisUserWorkload(vo.getId()));
        }
        for (int i = 0; i < list.size(); i++){
            try {
                Future<AnalysisUserWorkloadDTO> r = list.get(i);
                AnalysisUserWorkloadDTO dto = r.get();
                UserWorkloadExportVO vo = exportList.get(i);
                BeanUtil.copyProperties(dto,vo,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
                exportList.set(i,vo);
            } catch (InterruptedException | ExecutionException e) {
                // Handle appropriately, results.add(null) or just leave it out
                log.error(e.toString());
            }
        }

        //创建对应文件
        String filePath = fileParentPath+ File.separator+ioJob.getId()+File.separator+"工作量导出.xlsx";
        FileUtil.touch(filePath);

        System.out.println("filePath:"+filePath);

        EasyExcel.write(filePath, UserWorkloadExportVO.class).sheet("sheet").doWrite(exportList);
        // 保存文件路径
        ioJob.setFilePath(filePath);
        // 更新状态
        ioJob.setJobStatus(JobStatusConst.FINISHED);
        log.info("执行完成");
        return ResponseDTO.succData(ioJobService.updateOne(ioJob));
    }

    /**
     * 导出的字段为人员姓名、院系、工号、申报类型（论文、纵向课题等）、项目类型（标志性论文、省级重大项目等）、
     * 能唯一确定该项目的字段（例如，横向课题的项目编号）、工作量、追加分
     */

    /**
     * deptId 部门ID 如果未传递该参数，则导出全部部门工作量，传递该参数，则导出对应部门工作量
     * 只导出科研工作量
     */
    @GetMapping("users/workload/export/v2")
    @ApiOperation(value = "分析用户工作量并导出")
    public ResponseDTO<Object> exportWorkload(@RequestParam(value = "deptId",required = false) Long deptId) {
        IOJob ioJob = ioJobService.createExportJob("工作量导出记录");
        /*
          获取全部部门信息 并构建集合
         */
        List<SysDeptBasic> depts = deptService.getAllDeptBasic();
        Map<Long,String> deptMap = new HashMap<>();
        depts.forEach(ele->{
            deptMap.put(ele.getId(),ele.getDeptName());
        });

            /*
            获取全部岗位信息，并构建集合
         */
        List<NepuPost> posts = postService.getAll();
        Map<String,String> postTypeMap = new HashMap<>();
        Map<String,String> postGradeMap = new HashMap<>();
        Map<String,String> postLevelMap = new HashMap<>();
        posts.forEach(ele->{
            postTypeMap.put(ele.getId(),ele.getPostType());
            postGradeMap.put(ele.getId(),ele.getPostGrade());
            postLevelMap.put(ele.getId(),ele.getPostLevel());
        });

        /*
          获取用户列表
         */
        List<UserBaseVO> baseVOS = userService.getAllUserBase();
        // 过滤条件
        if (Validator.isNotEmpty(deptId)){
            baseVOS = baseVOS.stream().filter(ele -> ele.getDeptId().equals(deptId)).collect(Collectors.toList());
        }
        List<WorkloadExportVO> exportList = new ArrayList<>();
//        baseVOS.forEach(ele->{
//            WorkloadExportVO vo = new WorkloadExportVO();
//            BeanUtil.copyProperties(ele,vo, CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
//            vo.setDeptName(deptMap.get(ele.getDeptId()));
//
//            exportList.add(vo);
//        });
        // 存放 Future 结果的数组
        List<Future<List<WorkloadExportVO>>> list = new ArrayList<>();
        for (UserBaseVO userBaseVO:baseVOS){
            // 返回 List
            list.add(workloadService.UserWorkloadAnalysisV2(userBaseVO,deptMap.get(userBaseVO.getDeptId()),
                    postTypeMap.get(userBaseVO.getPostId()),postGradeMap.get(userBaseVO.getPostId()),
                    postLevelMap.get(userBaseVO.getPostId())));
        }
        for (int i = 0; i < list.size(); i++){
            try {
                Future<List<WorkloadExportVO>> r = list.get(i);
                List<WorkloadExportVO> eList = r.get();
                exportList.addAll(eList);
            } catch (InterruptedException | ExecutionException e) {
                // Handle appropriately, results.add(null) or just leave it out
                log.error(e.toString());
            }
        }

        //创建对应文件
        String filePath = fileParentPath+ File.separator+ioJob.getId()+File.separator+"工作量导出.xlsx";
        FileUtil.touch(filePath);

        EasyExcel.write(filePath, WorkloadExportVO.class).sheet("sheet").doWrite(exportList);
        // 保存文件路径
        ioJob.setFilePath(filePath);
        // 更新状态
        ioJob.setJobStatus(JobStatusConst.FINISHED);
        log.info("执行完成");
        return ResponseDTO.succData(ioJobService.updateOne(ioJob));
    }


    @GetMapping("users/teachWorkload/export")
    @ApiOperation(value = "教学工作量导出")
    public ResponseDTO<Object> exportTeachWorkload(@RequestParam(value = "deptId",required = false) Long deptId) {
        IOJob ioJob = ioJobService.createExportJob("教学工作量导出记录");
        /*
          获取全部部门信息 并构建集合
         */
        List<SysDeptBasic> depts = deptService.getAllDeptBasic();
        Map<Long,String> deptMap = new HashMap<>();
        depts.forEach(ele->{
            deptMap.put(ele.getId(),ele.getDeptName());
        });

            /*
            获取全部岗位信息，并构建集合
         */
        List<NepuPost> posts = postService.getAll();
        Map<String,String> postTypeMap = new HashMap<>();
        Map<String,String> postGradeMap = new HashMap<>();
        Map<String,String> postLevelMap = new HashMap<>();
        posts.forEach(ele->{
            postTypeMap.put(ele.getId(),ele.getPostType());
            postGradeMap.put(ele.getId(),ele.getPostGrade());
            postLevelMap.put(ele.getId(),ele.getPostLevel());
        });

        /*
          获取用户列表
         */
        List<UserBaseVO> baseVOS = userService.getAllUserBase();
        // 过滤条件
        if (Validator.isNotEmpty(deptId)){
            baseVOS = baseVOS.stream().filter(ele -> ele.getDeptId().equals(deptId)).collect(Collectors.toList());
        }
        List<TeachWorkloadExportVO> exportList = new ArrayList<>();
//        baseVOS.forEach(ele->{
//            WorkloadExportVO vo = new WorkloadExportVO();
//            BeanUtil.copyProperties(ele,vo, CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
//            vo.setDeptName(deptMap.get(ele.getDeptId()));
//
//            exportList.add(vo);
//        });
        // 存放 Future 结果的数组
        List<Future<List<TeachWorkloadExportVO>>> list = new ArrayList<>();
        for (UserBaseVO userBaseVO:baseVOS){
            // 返回 List
            list.add(workloadService.UserTeachWorkload(userBaseVO,deptMap.get(userBaseVO.getDeptId()),
                    postTypeMap.get(userBaseVO.getPostId()),postGradeMap.get(userBaseVO.getPostId()),
                    postLevelMap.get(userBaseVO.getPostId())));
        }
        for (int i = 0; i < list.size(); i++){
            try {
                Future<List<TeachWorkloadExportVO>> r = list.get(i);
                List<TeachWorkloadExportVO> eList = r.get();
                exportList.addAll(eList);
            } catch (InterruptedException | ExecutionException e) {
                // Handle appropriately, results.add(null) or just leave it out
                log.error(e.toString());
            }
        }

        //创建对应文件
        String filePath = fileParentPath+ File.separator+ioJob.getId()+File.separator+"教学工作量导出.xlsx";
        FileUtil.touch(filePath);

        EasyExcel.write(filePath, TeachWorkloadExportVO.class).sheet("sheet").doWrite(exportList);
        // 保存文件路径
        ioJob.setFilePath(filePath);
        // 更新状态
        ioJob.setJobStatus(JobStatusConst.FINISHED);
        log.info("执行完成");
        return ResponseDTO.succData(ioJobService.updateOne(ioJob));
    }

    @GetMapping("users/workload/type/export")
    @ApiOperation(value = "分析用户工作量级别并导出")
    public ResponseDTO<Object> exportWorkloadType(@RequestParam(value = "deptId",required = false) Long deptId) {
        IOJob ioJob = ioJobService.createExportJob("按类别导出工作量");
        /*
          获取全部部门信息 并构建集合
         */
        List<SysDeptBasic> depts = deptService.getAllDeptBasic();
        Map<Long,String> deptMap = new HashMap<>();
        depts.forEach(ele->{
            deptMap.put(ele.getId(),ele.getDeptName());
        });

            /*
            获取全部岗位信息，并构建集合
         */
        List<NepuPost> posts = postService.getAll();
        Map<String,String> postTypeMap = new HashMap<>();
        Map<String,String> postGradeMap = new HashMap<>();
        Map<String,String> postLevelMap = new HashMap<>();
        posts.forEach(ele->{
            postTypeMap.put(ele.getId(),ele.getPostType());
            postGradeMap.put(ele.getId(),ele.getPostGrade());
            postLevelMap.put(ele.getId(),ele.getPostLevel());
        });

        /*
          获取用户列表
         */
        List<UserBaseVO> baseVOS = userService.getAllUserBase();
        // 过滤条件
        if (Validator.isNotEmpty(deptId)){
            baseVOS = baseVOS.stream().filter(ele -> ele.getDeptId().equals(deptId)).collect(Collectors.toList());
        }
        List<TypeExportVO> exportList = new ArrayList<>();
        // 存放 Future 结果的数组
        List<Future<List<TypeExportVO>>> list = new ArrayList<>();
        for (UserBaseVO userBaseVO:baseVOS){
            // 返回 List
            list.add(workloadService.WorkloadType(userBaseVO,deptMap.get(userBaseVO.getDeptId()),
                    postTypeMap.get(userBaseVO.getPostId()),postGradeMap.get(userBaseVO.getPostId()),
                    postLevelMap.get(userBaseVO.getPostId())));
        }
        for (int i = 0; i < list.size(); i++){
            try {
                Future<List<TypeExportVO>> r = list.get(i);
                List<TypeExportVO> eList = r.get();
                exportList.addAll(eList);
            } catch (InterruptedException | ExecutionException e) {
                // Handle appropriately, results.add(null) or just leave it out
                log.error(e.toString());
            }
        }

        //创建对应文件
        String filePath = fileParentPath+ File.separator+ioJob.getId()+File.separator+"按类别导出工作量.xlsx";
        FileUtil.touch(filePath);

        EasyExcel.write(filePath, TypeExportVO.class).sheet("sheet").doWrite(exportList);
        // 保存文件路径
        ioJob.setFilePath(filePath);
        // 更新状态
        ioJob.setJobStatus(JobStatusConst.FINISHED);
        log.info("执行完成");
        return ResponseDTO.succData(ioJobService.updateOne(ioJob));
    }


    @GetMapping("users/workload/type/exportX")
    @ApiOperation(value = "分析用户工作量级别并导出(新版本)")
    public ResponseDTO<Object> exportWorkloadTypeX(@RequestParam(value = "deptId",required = false) Long deptId) {
        IOJob ioJob = ioJobService.createExportJob("按类别导出工作量");
        /*
          获取全部部门信息 并构建集合
         */
        List<SysDeptBasic> depts = deptService.getAllDeptBasic();
        Map<Long,String> deptMap = new HashMap<>();
        depts.forEach(ele->{
            deptMap.put(ele.getId(),ele.getDeptName());
        });

            /*
            获取全部岗位信息，并构建集合
         */
        List<NepuPost> posts = postService.getAll();
        Map<String,String> postTypeMap = new HashMap<>();
        Map<String,String> postGradeMap = new HashMap<>();
        Map<String,String> postLevelMap = new HashMap<>();
        posts.forEach(ele->{
            postTypeMap.put(ele.getId(),ele.getPostType());
            postGradeMap.put(ele.getId(),ele.getPostGrade());
            postLevelMap.put(ele.getId(),ele.getPostLevel());
        });
        /*
          获取用户列表
         */
        List<UserBaseVO> baseVOS = userService.getAllUserBase();
        // 过滤条件
        if (Validator.isNotEmpty(deptId)){
            baseVOS = baseVOS.stream().filter(ele -> ele.getDeptId().equals(deptId)).collect(Collectors.toList());
        }
        List<TypeExportXVO> exportList = new ArrayList<>();
        // 存放 Future 结果的数组
        List<Future<List<TypeExportXVO>>> list = new ArrayList<>();
        for (UserBaseVO userBaseVO:baseVOS){
            // 返回 List
            list.add(workloadService.WorkloadTypeX(userBaseVO,deptMap.get(userBaseVO.getDeptId()),
                    postTypeMap.get(userBaseVO.getPostId()),postGradeMap.get(userBaseVO.getPostId()),
                    postLevelMap.get(userBaseVO.getPostId())));
        }
        for (int i = 0; i < list.size(); i++){
            try {
                Future<List<TypeExportXVO>> r = list.get(i);
                List<TypeExportXVO> eList = r.get();
                exportList.addAll(eList);
            } catch (InterruptedException | ExecutionException e) {
                // Handle appropriately, results.add(null) or just leave it out
                log.error(e.toString());
            }
        }

        //创建对应文件
        String filePath = fileParentPath+ File.separator+ioJob.getId()+File.separator+"按类别导出工作量(新版本).xlsx";
        FileUtil.touch(filePath);

        EasyExcel.write(filePath, TypeExportXVO.class).sheet("sheet").doWrite(exportList);
        // 保存文件路径
        ioJob.setFilePath(filePath);
        // 更新状态
        ioJob.setJobStatus(JobStatusConst.FINISHED);
        log.info("执行完成");
        return ResponseDTO.succData(ioJobService.updateOne(ioJob));
    }

    @GetMapping("users/workload/export/total")
    @ApiOperation(value = "绩效导出")
    public ResponseDTO<Object> exportperformance(@RequestParam(value = "deptId",required = false) Long deptId) {
        IOJob ioJob = ioJobService.createExportJob("绩效导出记录");
        /*
          获取全部部门信息 并构建集合
         */
        List<SysDeptBasic> depts = deptService.getAllDeptBasic();
        Map<Long,String> deptMap = new HashMap<>();
        depts.forEach(ele->{
            deptMap.put(ele.getId(),ele.getDeptName());
        });

            /*
            获取全部岗位信息，并构建集合
         */
        List<NepuPost> posts = postService.getAll();
        Map<String,String> postTypeMap = new HashMap<>();
        Map<String,String> postGradeMap = new HashMap<>();
        Map<String,String> postLevelMap = new HashMap<>();
        Map<String,Double> targetTMap = new HashMap<>();
        Map<String,Double> targetRMap = new HashMap<>();
        Map<String,Double> standard = new HashMap<>();

        posts.forEach(ele->{
            postTypeMap.put(ele.getId(),ele.getPostType());
            postGradeMap.put(ele.getId(),ele.getPostGrade());
            postLevelMap.put(ele.getId(),ele.getPostLevel());
            targetTMap.put(ele.getId(),ele.getTeachWorkload());
            targetRMap.put(ele.getId(),ele.getResearchWorkload());
            standard.put(ele.getId(),ele.getStandard());
        });

        /*
          获取用户列表
         */
        List<UserBaseVO> baseVOS = userService.getAllUserBase();
        // 过滤条件
        if (Validator.isNotEmpty(deptId)){
            baseVOS = baseVOS.stream().filter(ele -> ele.getDeptId().equals(deptId)).collect(Collectors.toList());
        }
//        baseVOS.forEach(ele->{
//            WorkloadExportVO vo = new WorkloadExportVO();
//            BeanUtil.copyProperties(ele,vo, CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
//            vo.setDeptName(deptMap.get(ele.getDeptId()));
//
//            exportList.add(vo);
//        });
        // 存放 Future 结果的数组
        List<FinalWorkloadExportVO> list = new ArrayList<>();
        for (UserBaseVO userBaseVO:baseVOS){
            // 返回 List
            list.add(workloadService.performanceAnalysis(userBaseVO,deptMap.get(userBaseVO.getDeptId()),
                    postTypeMap.get(userBaseVO.getPostId()),postGradeMap.get(userBaseVO.getPostId()),
                    postLevelMap.get(userBaseVO.getPostId()),targetTMap.get(userBaseVO.getPostId()),
                    targetRMap.get(userBaseVO.getPostId()),standard.get(userBaseVO.getPostId())));
        }

        //创建对应文件
        String filePath = fileParentPath+ File.separator+ioJob.getId()+File.separator+"绩效工作量导出.xlsx";
        FileUtil.touch(filePath);
        EasyExcel.write(filePath, FinalWorkloadExportVO.class).sheet("sheet").doWrite(list);
        // 保存文件路径
        ioJob.setFilePath(filePath);
        // 更新状态
        ioJob.setJobStatus(JobStatusConst.FINISHED);
        log.info("执行完成");
        return ResponseDTO.succData(ioJobService.updateOne(ioJob));
    }


    @GetMapping("users/topic/export")
    @ApiOperation(value = "科研处审核纵向课题导出")
    public ResponseDTO<Object> exportTopic(@RequestParam(value = "deptId",required = false) Long deptId) {
        IOJob ioJob = ioJobService.createExportJob("按类别导出工作量");

        List<TopicExportVO> list = new ArrayList<>();
        list = workloadService.topicData();

        //创建对应文件
        String filePath = fileParentPath+ File.separator+ioJob.getId()+File.separator+"科研处审核纵向课题导出.xlsx";
        FileUtil.touch(filePath);

        EasyExcel.write(filePath, TopicExportVO.class).sheet("sheet").doWrite(list);
        // 保存文件路径
        ioJob.setFilePath(filePath);
        // 更新状态
        ioJob.setJobStatus(JobStatusConst.FINISHED);
        log.info("执行完成");
        return ResponseDTO.succData(ioJobService.updateOne(ioJob));
    }




}
